#include <avr/io.h>
#include "key.h"
#include "global.h"
#include "OLED.h"
#include "spi.h"

#if EXT_SERIAL_EN
static int putch(char c, FILE *stream);
static FILE _stdout = FDEV_SETUP_STREAM(putch, NULL,_FDEV_SETUP_WRITE); 

#endif

const uint8_t key_value_map[] = {
	250, 231, 210, 186, 158, 126, 86, 0,
};

#define START_ADC()		setbit(ADCA.CH1.CTRL, 7)
#define WAIT_CONVERT()		do{ while(!testbit(ADCA.CH1.INTFLAGS,0)); ADCA.CH1.INTFLAGS = 1;}while(0)
void ms_delay(uint16_t ms)
{
	volatile uint16_t i;
	while(ms--) {
		for(i = 0; i<90; i++);// Test at 32M Clock
	}
}
void short_delay(void)
{
	ms_delay(10);
}
void long_delay(void)
{
	ms_delay(500);
}

void key_init(void)
{
#if EXT_SERIAL_EN
	// Initialize USARTE0 for External Interface Port
	USARTE0.BAUDCTRLA = 0x08;	// BSCALE = -6, BSEL = 1047
	USARTE0.BAUDCTRLB = 0xA0;	// ==> 115211 bps (~115.2kbps)
	USARTE0.CTRLC	  = 0x03;	// Async, No Parity, 1 stop bit, 8 data bits
	USARTE0.CTRLB	  = 0x08;	// Enable TX
	stdout = &_stdout;
	printf("Hello World\n");
#endif

	// ADC
	ADCA.CALL = SP_ReadCalibrationByte(0x20);
	ADCA.CALH = SP_ReadCalibrationByte(0x21);

	ADCA.CTRLB = 0x64;			// High current limit, signed mode, no free run, 8 bit
	ADCA.PRESCALER = 0x07;		// Prescaler 512 (62.5kHZ ADC clock)
	ADCA.CTRLA		  = 0x01;	// Enable ADC

	ADCA.REFCTRL	  = 0x10;	// REF= VCC/1.6 (3.3V/1.6 = 2.0625V)
	ADCA.CH1.MUXCTRL  = 0x08;	// Channel 1 input: ADC1 pin
	ADCA.CH1.CTRL	  = 0x01;	// Single-ended positive input signal
}

uint8_t get_key_value(void)
{
	uint8_t key, adc, pressed = KEY_NONE;

	do{
		if(testbit(PORT_CTRL_IN,PIN_KEY_MAIN)) {
			key = KEY_MAIN;
		} else	{
			START_ADC();
			WAIT_CONVERT();
			adc = ADCA.CH1.RESL;
			if(adc > 250) {
				key = KEY_NONE;
			} else {
				short_delay();
				START_ADC();
				WAIT_CONVERT();
				adc = ADCA.CH1.RESL;
				for(key = 0; key < 8; key++) {
					if(adc >= key_value_map[key]) {
						break;
					}
				}
			}
		}
		if(key != KEY_NONE) {
			pressed = key;
			short_delay();
		}		
	}while(key != KEY_NONE);

	return pressed;
}

#if EXT_SERIAL_EN
static int putch(char c, FILE *stream)

{
	(void)(stream);

    while ( !testbit(USARTE0.STATUS,USART_DREIF_bp) ) ;  // wait until ready to transmit
    USARTE0.DATA = c;

	return 0;
}

#endif

